package com.vcc.web.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.map.MapUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSONObject;
import com.mybatisflex.core.paginate.Page;
import com.vcc.channel.base.model.request.CardRechargeDto;
import com.vcc.channel.base.model.request.CreateCardHolderDto;
import com.vcc.channel.base.model.request.TransferDto;
import com.vcc.channel.base.service.ChannelBaseService;
import com.vcc.core.annotations.KycReject;
import com.vcc.core.annotations.ROReject;
import com.vcc.core.annotations.RepeatSubmit;
import com.vcc.core.annotations.RestPack;
import com.vcc.core.constant.CardTypeEnum;
import com.vcc.core.exception.ProgramException;
import com.vcc.core.exception.SignInException;
import com.vcc.core.util.CardholderUtil;
import com.vcc.core.util.IdWorker;
import com.vcc.data.entity.*;
import com.vcc.service.boss.share.config.response.BossShareAccountConfigResponse;
import com.vcc.service.client.dto.card.ClientShareCardRequestRequest;
import com.vcc.service.client.dto.card.RequestCardDto;
import com.vcc.service.client.dto.cardholder.ClientCardholderCreateRequest;
import com.vcc.service.client.vo.card.CardTypeVo;
import com.vcc.service.service.*;
import com.vcc.web.core.component.RedisComponent;
import com.vcc.web.core.util.UserUtil;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

@RestController
@RequestMapping("card")
public class CardController {

    private static final Logger log = LogManager.getLogger(CardController.class);

    @Autowired
    private CardTypeService cardService;
    @Autowired
    private WalletService walletService;
    @Autowired
    private UserService userService;
    @Autowired
    private RedisComponent redisComponent;
    @Autowired
    private ReserveCardService reserveCardService;
    @Resource
    private ApplicationContext applicationContext;
    @Resource
    private UserCardWalletService userCardWalletService;
    @Resource
    private CardholderService cardholderService;
    @Resource
    private UserCardService userCardService;
    @Resource
    private CardOrderService cardOrderService;
    @Resource
    private ClientParamService clientParamService;
    @Resource
    private RedissonClient redissonClient;
    @Autowired
    private CardGroupService cardGroupService;
    @Autowired
    private ShareAccountConfigService shareAccountConfigService;
    @Autowired
    private ChannelService channelService;
    @Autowired
    private ShareAccountService shareAccountService;
    @Autowired
    private ShareAccountDetailService shareAccountDetailService;


    @RestPack
    @GetMapping("paging")
    @SaCheckLogin
    @SaCheckPermission("card:bin:view")
    public Page<CardTypeVo> paging(
            Integer pageNumber,
            Integer pageSize,
            String sectionNo,
            String scenes,
            boolean hasShare
    ) {
        User user = UserUtil.get();
        Page<CardType> paging = cardService.paging(
                Page.of(
                        pageNumber == null ? 1 : pageNumber,
                        pageSize == null ? 20 : pageSize
                ),
                null,
                sectionNo,
                0,
                scenes,
                !hasShare ? "normal" : "share"
        );
        List<BossShareAccountConfigResponse> shareList;
        List<UserCardWallet> userCardWallets;
        if (hasShare) {
            userCardWallets = List.of();
            shareList = shareAccountConfigService.listByUserId(user.getId());
        } else {
            shareList = List.of();
            userCardWallets = userCardWalletService.listByUserId(user.getId());
        }
        return paging.map(it -> {
            if (hasShare) {
                if (shareList.isEmpty()) {
                    return new CardTypeVo(it);
                }
                BossShareAccountConfigResponse first = shareList.stream().filter(bossShareAccountConfigResponse -> Objects.equals(it.getId(), bossShareAccountConfigResponse.getCardTypeId())).findFirst().orElse(null);
                return first == null ? new CardTypeVo(it) : new CardTypeVo(it, first);

            } else {
                if (userCardWallets.isEmpty()) {
                    return new CardTypeVo(it);
                }
                UserCardWallet first = userCardWallets.stream().filter(userCardWallet -> Objects.equals(it.getId(), userCardWallet.getCardId())).findFirst().orElse(null);
                return first == null ? new CardTypeVo(it) : new CardTypeVo(it, first);
            }
        });

    }

    @RestPack
    @GetMapping("get")
    @SaCheckPermission("card:bin:view")
    public CardTypeVo get(
            Long id
    ) {
        CardType card = cardService.getById(id);
        return new CardTypeVo(card);
    }

    @ROReject
    @KycReject
    @RestPack
    @SaCheckPermission("card:request")
    @PostMapping("requestCard")
    @RepeatSubmit
    public Boolean requestCard(
            @RequestBody RequestCardDto requestCardDto
    ) {
        User user = UserUtil.get();
        if (!user.getStatus().equals(0)) {
            throw new SignInException("您当前状态无法开卡");
        }
        CardGroup cardGroup = cardGroupService.getByIdOpt(requestCardDto.getGroupId()).orElseThrow(() -> new ProgramException("卡组不存在"));
        if (cardGroup.getStatus() != 0) {
            throw new ProgramException("当前卡组不支持开卡");
        }
        if (!Objects.equals(cardGroup.getUserId(), user.getId())) {
            throw new ProgramException("非法操作");
        }
        RLock lock = redissonClient.getLock("requestCard:" + user.getId());
        try {
            boolean tryLock = lock.tryLock();
            if (!tryLock) {
                throw new ProgramException("请勿重复提交");
            }
            CardType card = cardService.getById(requestCardDto.getId());
            if (Objects.equals(requestCardDto.getAmount().compareTo(BigDecimal.valueOf(0)), -1)) {
                throw new ProgramException("金额不能小于0");
            }
            if (requestCardDto.getCount() < 1) {
                throw new ProgramException("申请数量不能小于1");
            }
            if (card.getVerifyOpenCardStatus() != 0) {
                throw new ProgramException("不支持您开当前卡种");
            }
            UserCardWallet userCardWallet = userCardWalletService.findByUserIdAndCardId(user.getId(), card.getId());
            if (userCardWallet.getAmount().compareTo(BigDecimal.ZERO) < 0) {
                throw new ProgramException("您当前开卡费尚未调整");
            }
            Long count = userCardService.countByUserId(user.getId());
            String openCardLimit = clientParamService.getValueByCodeAndUserId("OPEN_CARD_LIMIT", user.getId());
            if (count + requestCardDto.getCount() > Long.parseLong(openCardLimit)) {
                throw new ProgramException("您当前开卡数量已达上限");
            }
            //总开卡金额
            BigDecimal tempOpenCardAmount = userCardWallet.getAmount().multiply(BigDecimal.valueOf(requestCardDto.getCount())).setScale(2, RoundingMode.HALF_UP);
            //总充值金额
            BigDecimal tempRechargeAmount = requestCardDto.getAmount().multiply(BigDecimal.valueOf(requestCardDto.getCount())).setScale(2, RoundingMode.HALF_UP);
            Wallet wallet = walletService.getByUserIdAndCurrencyCode(user.getId(), card.getCurrencyCode());
            BigDecimal tempSumAmount = tempOpenCardAmount.add(tempRechargeAmount).setScale(2, RoundingMode.HALF_UP);
            if (Objects.equals(userCardWallet.getExchangeRate().compareTo(BigDecimal.valueOf(0)), 1)) {
                BigDecimal tempExchangeRateAmount = userCardWallet.getExchangeRate()
                        .divide(BigDecimal.valueOf(100), 4, RoundingMode.HALF_UP)
                        .multiply(requestCardDto.getAmount());
                tempExchangeRateAmount = tempExchangeRateAmount
                        .multiply(BigDecimal.valueOf(requestCardDto.getCount()))
                        .setScale(2, RoundingMode.HALF_UP);
                tempSumAmount = tempSumAmount.add(tempExchangeRateAmount).setScale(2, RoundingMode.HALF_UP);
            }
            if (Objects.equals(tempSumAmount.compareTo(wallet.getUsableQuota()), 1)) {
                throw new ProgramException("您" + card.getCurrencyName() + "钱包余额不足");
            }
            ChannelBaseService channelBaseService = (ChannelBaseService) applicationContext.getBean(card.getChannelName());
            String cardholderId = "";
            Long alCardholderId = 0L;
            if (!requestCardDto.getSystemCreateCardholder()) {
                Cardholder cardholder = cardholderService.getByIdOpt(requestCardDto.getCardholderId()).orElseThrow(() -> new ProgramException("持卡人不存在"));
                JSONObject cardholderInfo = JSONUtil.toBean(cardholder.getCardholderInfo(), JSONObject.class);
                List<JSONObject> photonCardholderList = cardholderInfo.getJSONArray("PhotonPay").toList(JSONObject.class);
                JSONObject accountInfo = photonCardholderList.get(0);
                cardholderId = accountInfo.getString("value");
                alCardholderId = cardholder.getId();
            }
            //待改造
            for (int i = 0; i < requestCardDto.getCount(); i++) {
                //生成请求ID
                String requestId = IdWorker.getStringOrderId();
                if (requestCardDto.getSystemCreateCardholder()) {
                    if (requestCardDto.getHasSingleCardholder()) {
                        if (Objects.equals(cardholderId, "")) {
                            ClientCardholderCreateRequest clientCardholderCreateRequest = generateCardholderDto(requestCardDto, requestId, user);
                            String channelCardholderId = channelGenerateCardholder(clientCardholderCreateRequest, channelBaseService);
                            Cardholder cardholder = saveCardholder(clientCardholderCreateRequest, channelCardholderId);
                            cardholderId = channelCardholderId;
                            alCardholderId = cardholder.getId();
                        }
                    } else {
                        ClientCardholderCreateRequest clientCardholderCreateRequest = generateCardholderDto(requestCardDto, requestId, user);
                        String channelCardholderId = channelGenerateCardholder(clientCardholderCreateRequest, channelBaseService);
                        Cardholder cardholder = saveCardholder(clientCardholderCreateRequest, channelCardholderId);
                        cardholderId = channelCardholderId;
                        alCardholderId = cardholder.getId();
                    }
                }
                walletService.openCard(
                        user.getId(),
                        user.getId(),
                        card.getCurrencyCode(),
                        requestId,
                        card.getId(),
                        card.getChannelName(),
                        userCardWallet.getAmount(),
                        requestCardDto.getRemark(),
                        "CLIENT"
                );
                cardOrderService.openCard(
                        null,
                        requestId,
                        card.getId(),
                        user.getId(),
                        user.getId(),
                        card.getChannelName(),
                        userCardWallet.getAmount(),
                        card.getCurrencyCode(),
                        requestCardDto.getRemark(),
                        "CLIENT"
                );
//                switch (card.getChannelName()) {
//                    case "PhotonPay":
                HashMap<String, Object> requestCardParams = MapUtil.newHashMap();
                requestCardParams.put("requestId", requestId);
                requestCardParams.put("cardholderId", cardholderId);
                requestCardParams.put("cardBin", card.getSectionNo());
                requestCardParams.put("amount", requestCardDto.getAmount());
                requestCardParams.put("cardTypeId", card.getId());
                requestCardParams.put("userId", user.getId());
                requestCardParams.put("remark", StringUtils.isBlank(requestCardDto.getRemark()) ? "" : requestCardDto.getRemark());
                requestCardParams.put("alCardholderId", alCardholderId);
                requestCardParams.put("groupId", cardGroup.getId());
                requestCardParams.put("type", CardTypeEnum.NORMAL.getCode());
                Boolean result = (Boolean) channelBaseService.openCard(requestCardParams);
                if (result && requestCardDto.getAmount().compareTo(BigDecimal.ZERO) > 0) {
                    UserCard userCard = userCardService.getByOrderId(requestId);
                    String rechargeRequestId = IdWorker.getStringOrderId();
                    walletService.cardRecharge(
                            user.getId(),
                            user.getId(),
                            card.getCurrencyCode(),
                            rechargeRequestId,
                            card.getId(),
                            userCard.getCardNumber(),
                            userCard.getId(),
                            card.getChannelName(),
                            requestCardDto.getAmount(),
                            requestCardDto.getRemark(),
                            "CLIENT"
                    );
                    cardOrderService.rechargeCard(
                            rechargeRequestId,
                            card.getId(),
                            user.getId(),
                            user.getId(),
                            userCard.getCardNumber(),
                            userCard.getId(),
                            card.getChannelName(),
                            requestCardDto.getAmount(),
                            card.getCurrencyCode(),
                            requestCardDto.getRemark(),
                            "CLIENT"
                    );
                    channelBaseService.recharge(
                            CardRechargeDto.builder()
                                    .channelCardId(userCard.getChannelCardId())
                                    .rechargeAmount(requestCardDto.getAmount())
                                    .requestId(rechargeRequestId)
                                    .cardNumberId(userCard.getId())
                                    .cardNumber(userCard.getCardNumber())
                                    .build()
                    );
                }
//                break;

//                    default:
//                        throw new ProgramException("不支持的渠道");
//                }
            }
        } catch (Exception e) {
            log.error("开卡失败", e);
            if (e instanceof ProgramException) {
                throw e;
            }
            throw new ProgramException("开卡失败，请稍后再试");
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
        return true;
    }


    @ROReject
    @KycReject
    @RestPack
    @SaCheckPermission("card:request")
    @PostMapping("requestShareCard")
    @RepeatSubmit
    public Boolean requestShareCard(
            @RequestBody @Validated ClientShareCardRequestRequest requestCardDto
    ) {
        User user = UserUtil.get();
        if (!user.getStatus().equals(0)) {
            throw new SignInException("您当前状态无法开卡");
        }
        CardGroup cardGroup = cardGroupService.getByIdOpt(requestCardDto.getGroupId()).orElseThrow(() -> new ProgramException("卡组不存在"));
        if (cardGroup.getStatus() != 0) {
            throw new ProgramException("当前卡组不支持开卡");
        }
        if (!Objects.equals(cardGroup.getUserId(), user.getId())) {
            throw new ProgramException("非法操作");
        }
        RLock lock = redissonClient.getLock("requestCard:" + user.getId());
        try {
            boolean tryLock = lock.tryLock();
            if (!tryLock) {
                throw new ProgramException("请勿重复提交");
            }
            CardType card = cardService.getById(requestCardDto.getId());
            if (requestCardDto.getCount() < 1) {
                throw new ProgramException("申请数量不能小于1");
            }
            if (card.getVerifyOpenCardStatus() != 0) {
                throw new ProgramException("不支持您开当前卡种");
            }
            ShareAccountConfig shareAccountConfig = shareAccountConfigService.getByUserIdAndCardTypeId(user.getId(), card.getId());
            if (shareAccountConfig == null || shareAccountConfig.getStatus() != 0) {
                throw new ProgramException("您当前卡种未配置共享账户");
            }
            if (shareAccountConfig.getVerifyOpenCardStatus() != 0) {
                throw new ProgramException("您当前卡种不支持开卡");
            }
            Channel channel = channelService.getByCode(card.getChannelName());
            if (!channel.getHasShareAccount()) {
                throw new ProgramException("该渠道未开启共享账户功能");
            }
            ShareAccount shareAccount = shareAccountService.getByIdOpt(shareAccountConfig.getShareAccountId()).orElseThrow(() -> new ProgramException("共享账户不存在"));
            if (shareAccountConfig.getAmount().compareTo(BigDecimal.ZERO) < 0) {
                throw new ProgramException("您当前开卡费尚未调整");
            }
            Long count = userCardService.countByUserId(user.getId());
            String openCardLimit = clientParamService.getValueByCodeAndUserId("OPEN_CARD_LIMIT", user.getId());
            if (count + requestCardDto.getCount() > Long.parseLong(openCardLimit)) {
                throw new ProgramException("您当前开卡数量已达上限");
            }
            //总开卡金额
            BigDecimal tempOpenCardAmount = shareAccountConfig.getAmount().multiply(BigDecimal.valueOf(requestCardDto.getCount())).setScale(2, RoundingMode.HALF_UP);
            ChannelBaseService channelBaseService = (ChannelBaseService) applicationContext.getBean(card.getChannelName());

            BigDecimal balance = channelBaseService.queryAccountBalance(shareAccount.getAccountId());
            if (Objects.equals(tempOpenCardAmount.compareTo(balance), 1)) {
                throw new ProgramException("您" + shareAccount.getAccountName() + "余额不足");
            }


            String cardholderId = "";
            Long alCardholderId = 0L;
            //待改造
            for (int i = 0; i < requestCardDto.getCount(); i++) {
                //生成请求ID
                String requestId = IdWorker.getStringOrderId();
                TransferDto transferDto = new TransferDto();
                transferDto.setAccountId(shareAccount.getAccountId());
                transferDto.setAmount(shareAccountConfig.getAmount());
                transferDto.setType("transfer_out");
                Boolean transfer = channelBaseService.transfer(transferDto);
                if (transfer) {

                    shareAccountDetailService.create(
                            shareAccount.getId(),
                            channelBaseService.queryAccountBalance(shareAccount.getAccountId()),
                            "USD",
                            shareAccount.getChannelCode(),
                            "OPEN",
                            requestId,
                            shareAccountConfig.getAmount(),
                            requestCardDto.getRemark(),
                            false,
                            card.getId(),
                            null,
                            shareAccount.getUserId(),
                            UserUtil.getId()
                    );
                } else {
                    throw new ProgramException("开卡失败，账户扣款异常");
                }
                if (requestCardDto.getHasSingleCardholder()) {
                    if (Objects.equals(cardholderId, "")) {
                        ClientCardholderCreateRequest clientCardholderCreateRequest = generateShareCardholderDto(requestCardDto, shareAccount.getAccountId(), shareAccount.getId(), requestId, user);
                        String channelCardholderId = channelGenerateCardholder(clientCardholderCreateRequest, channelBaseService);
                        Cardholder cardholder = saveCardholder(clientCardholderCreateRequest, channelCardholderId);
                        cardholderId = channelCardholderId;
                        alCardholderId = cardholder.getId();
                    }
                } else {
                    ClientCardholderCreateRequest clientCardholderCreateRequest = generateShareCardholderDto(requestCardDto, shareAccount.getAccountId(), shareAccount.getId(), requestId, user);
                    String channelCardholderId = channelGenerateCardholder(clientCardholderCreateRequest, channelBaseService);
                    Cardholder cardholder = saveCardholder(clientCardholderCreateRequest, channelCardholderId);
                    cardholderId = channelCardholderId;
                    alCardholderId = cardholder.getId();
                }

                cardOrderService.openCard(
                        shareAccount.getId(),
                        requestId,
                        card.getId(),
                        user.getId(),
                        user.getId(),
                        card.getChannelName(),
                        shareAccountConfig.getAmount(),
                        card.getCurrencyCode(),
                        requestCardDto.getRemark(),
                        "CLIENT"
                );
                HashMap<String, Object> requestCardParams = MapUtil.newHashMap();
                requestCardParams.put("requestId", requestId);
                requestCardParams.put("cardholderId", cardholderId);
                requestCardParams.put("cardBin", card.getSectionNo());
                requestCardParams.put("cardTypeId", card.getId());
                requestCardParams.put("userId", user.getId());
                requestCardParams.put("remark", StringUtils.isBlank(requestCardDto.getRemark()) ? "" : requestCardDto.getRemark());
                requestCardParams.put("alCardholderId", alCardholderId);
                requestCardParams.put("accountId", shareAccount.getAccountId());
                requestCardParams.put("shareAccountId", shareAccount.getId());
                requestCardParams.put("groupId", cardGroup.getId());
                requestCardParams.put("limit", requestCardDto.getLimit());
                requestCardParams.put("type",CardTypeEnum.SHARE.getCode());
                channelBaseService.openShareCard(requestCardParams);
            }
        } catch (Exception e) {
            log.error("开卡失败", e);
            if (e instanceof ProgramException) {
                throw e;
            }
            throw new ProgramException("开卡失败，请稍后再试");
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
        return true;
    }


    public ClientCardholderCreateRequest generateCardholderDto(RequestCardDto requestCardDto, String orderId, User user) {
        String email;
        do {
            email = CardholderUtil.createRandomEmail(orderId);
        } while (cardholderService.existsEmailByUserId(email, user.getId()));
        JSONObject addressInfo = CardholderUtil.getUsAddress();
        ClientCardholderCreateRequest clientCardholderCreateRequest = new ClientCardholderCreateRequest();
        clientCardholderCreateRequest.setFirstName(CardholderUtil.createName(6));
        clientCardholderCreateRequest.setLastName(CardholderUtil.createName(6));
        clientCardholderCreateRequest.setCountry("US");
        clientCardholderCreateRequest.setProvince(addressInfo.getString("state"));
        clientCardholderCreateRequest.setCity(addressInfo.getString("city"));
        clientCardholderCreateRequest.setArea(addressInfo.getString("aero"));
        clientCardholderCreateRequest.setPostCode(addressInfo.getString("zipcode"));
        clientCardholderCreateRequest.setAddress(addressInfo.getString("address"));
        clientCardholderCreateRequest.setPhone(CardholderUtil.createUsMobile());
        clientCardholderCreateRequest.setEmail(email);
        clientCardholderCreateRequest.setRemark(requestCardDto.getRemark());
        clientCardholderCreateRequest.setBirthday(CardholderUtil.createBirthday());
        clientCardholderCreateRequest.setMobilePrefix("01");
        return clientCardholderCreateRequest;
    }

    public ClientCardholderCreateRequest generateShareCardholderDto(ClientShareCardRequestRequest requestCardDto, String accountId, Long shareAccountId, String orderId, User user) {
        String email;
        do {
            email = CardholderUtil.createRandomEmail(orderId);
        } while (cardholderService.existsEmailByUserId(email, user.getId()));
        JSONObject addressInfo = CardholderUtil.getUsAddress();
        ClientCardholderCreateRequest clientCardholderCreateRequest = new ClientCardholderCreateRequest();
        clientCardholderCreateRequest.setFirstName(CardholderUtil.createName(6));
        clientCardholderCreateRequest.setLastName(CardholderUtil.createName(6));
        clientCardholderCreateRequest.setCountry("US");
        clientCardholderCreateRequest.setProvince(addressInfo.getString("state"));
        clientCardholderCreateRequest.setCity(addressInfo.getString("city"));
        clientCardholderCreateRequest.setArea(addressInfo.getString("aero"));
        clientCardholderCreateRequest.setPostCode(addressInfo.getString("zipcode"));
        clientCardholderCreateRequest.setAddress(addressInfo.getString("address"));
        clientCardholderCreateRequest.setPhone(CardholderUtil.createUsMobile());
        clientCardholderCreateRequest.setEmail(email);
        clientCardholderCreateRequest.setRemark(requestCardDto.getRemark());
        clientCardholderCreateRequest.setBirthday(CardholderUtil.createBirthday());
        clientCardholderCreateRequest.setMobilePrefix("01");
        clientCardholderCreateRequest.setAccountId(accountId);
        clientCardholderCreateRequest.setShareAccountId(shareAccountId);
        return clientCardholderCreateRequest;
    }

    private String channelGenerateCardholder(ClientCardholderCreateRequest clientCardholderCreateRequest, ChannelBaseService channelBaseService) {
        String cardHolder = channelBaseService.createCardHolder(
                CreateCardHolderDto.builder()
                        .firstName(clientCardholderCreateRequest.getFirstName())
                        .lastName(clientCardholderCreateRequest.getLastName())
                        .email(clientCardholderCreateRequest.getEmail())
                        .mobile(clientCardholderCreateRequest.getPhone())
                        .country(clientCardholderCreateRequest.getCountry())
                        .state(clientCardholderCreateRequest.getProvince())
                        .city(clientCardholderCreateRequest.getCity())
                        .area(clientCardholderCreateRequest.getArea())
                        .zipCode(clientCardholderCreateRequest.getPostCode())
                        .address(clientCardholderCreateRequest.getAddress())
                        .mobilePrefix(clientCardholderCreateRequest.getMobilePrefix())
                        .birthDay(clientCardholderCreateRequest.getBirthday())
                        .accountId(clientCardholderCreateRequest.getAccountId())
                        .build()
        );
        return cardHolder;
    }

    private Cardholder saveCardholder(ClientCardholderCreateRequest clientCardholderCreateRequest, String cardHolder) {
        HashMap<String, Object> info = new HashMap<>();
        ArrayList<HashMap<String, Object>> accounts = new ArrayList<>();
        HashMap<String, Object> account = new HashMap<>();
        account.put("account", "V1");
        account.put("value", cardHolder);
        accounts.add(account);
        info.put("PhotonPay", accounts);
        clientCardholderCreateRequest.setCardholderInfo(JSONUtil.toJsonStr(info));
        return cardholderService.createCardholder(UserUtil.getId(), clientCardholderCreateRequest);
    }

}
